require 'digest/sha1'

class User < ActiveRecord::Base
  include Authentication
  include Authentication::ByPassword
  include Authentication::ByCookieToken

  validates_presence_of     :nick_name
  validates_length_of       :nick_name,    :within => 3..20
  #validates_uniqueness_of   :nick_name
  validates_format_of       :nick_name,    :with => Authentication.login_regex, :message => Authentication.bad_login_message

  #validates_format_of       :name,     :with => Authentication.name_regex,  :message => Authentication.bad_name_message, :allow_nil => true
  #validates_length_of       :name,     :maximum => 100

  validates_presence_of     :email
  validates_length_of       :email,    :within => 6..100 #r@a.wk
  #validates_uniqueness_of   :email
  validates_format_of       :email,    :with => Authentication.email_regex, :message => 	Authentication.bad_email_message

	attr_accessor :province, :city
  #before_create :make_activation_code
  after_create :create_user_verify
  
  before_save	:parse_city
  
  #attr_accessible :nick_name, :email, :user_name, :real_name, :password, :password_confirmation, 
  #                :last_login_time, :signature, :blog_url, :site_url, :user_pic, :self_intro
  
  has_many :friendships, :dependent => :destroy
  has_many :friends, :through => :friendships, :class_name => 'User'
  has_many :user_favorite_subjects, :dependent => :destroy
  has_many :messages, :foreign_key => 'send_user_id', :dependent => :destroy
  has_many :item_alliances, :dependent => :destroy
  has_many :picture_comments, :dependent => :destroy
  has_many :item_ratings, :dependent => :destroy
  has_many :item_rating_replies, :dependent => :destroy
  has_many :user_verifies, :dependent => :destroy
  has_many :user_operation_records, :dependent => :destroy
  has_many :user_item_interests, :dependent => :destroy
  has_many :items, :through => :user_item_interests
  has_many :item_review_votes #  投票
  has_one	 :user_icon

#  def after_create
#     UserFavoriteSubject.create! :user_id => id, :title => 'Default'
#     UserVerify.create! :user_id => id, :verify_code => generateVerifyCode
#  end
#  
#  def generateVerifyCode
#    chars = ("a".."z").to_a + ("A".."Z").to_a + ("0".."9").to_a
#    newpass = ""
#    1.upto(20) { |i| newpass << chars[rand(chars.size-1)] }
#    return newpass    
#  end


  # Activates the user in the database.
  def activate!
    @activated = true
    signup_user_verify.update_attributes!(:status => 1)
#    self.activated_at = Time.now.utc
#    self.activation_code = nil
#    save(false)
  end

  # Returns true if the user has just been activated.
  def recently_activated?
    @activated
  end

  def active?
    # the existence of an activation code means they have not activated yet
    #activation_code.nil?
    !!signup_user_verify.nil?
  end
  
  def signup_user_verify
    user_verifies.find_by_status_and_flag(0, 0)
  end
  
  def password_user_verify
    user_verifies.find_by_status_and_flag(0, 1)
  end

  # Authenticates a user by their login name and unencrypted password.  Returns the user or nil.
  #
  # uff.  this is really an authorization, not authentication routine.  
  # We really need a Dispatch Chain here or something.
  # This will also let us return a human error message.
  #
  def self.authenticate(email, password)
    return nil if email.blank? || password.blank?
    #u = find :first, :conditions => ['nick_name = ? and activated_at IS NOT NULL', nick_name] # need to get the salt
    u = first(:conditions => ['email = ?', email])
    u && u.authenticated?(password) ? u : nil
  end

  def nick_name=(value)
    write_attribute :nick_name, (value ? value.downcase : nil)
  end

  def email=(value)
    write_attribute :email, (value ? value.downcase : nil)
  end
  
  def self.unique_email?(email)
  	find_by_email(email)
  end
  
	def reset_pwd(new_pass)
	  update_attributes!(:password => new_pass)
  end
  
  def password=(pwd)
    return if pwd.blank?
    create_new_salt
    self.crypted_password = self.class.encrypted_password(pwd, self.salt)
  end
    
  def authenticated?(password)
    crypted_password == self.class.encrypted_password(password, self.salt)
  end
  
	
  protected
  
    def create_user_verify
       user_verifies.create!(:nick_name => nick_name, :email => email, :verify_code => make_verify_code)
    end
    
    def make_verify_code
      self.class.make_token
    end
    
    def make_activation_code
      self.activation_code = self.class.make_token
    end
    
    def parse_city
    	return if self.province.blank? || self.city.blank?
    	if self.province.include?("请选择") || self.city.include?("请选择") 
    		self.living_city = nil
  		else
	    	self.living_city = self.province + "|" + self.city
    	end
    end
    
  private
  	def self.encrypted_password(pwd,salt)
		  string_to_hash = "#{pwd}@re54#4e!#{salt}"
		  Digest::SHA1.hexdigest(string_to_hash)
		end
  
		def create_new_salt
		  self.salt = Digest::SHA1.hexdigest(Time.now.to_s + rand.to_s)
		end
		
		def reprocess_pic
    	pic.reprocess!
    	
    	#copy pic
    	#保存坐标
  	end
end
